#pragma once


#include "SkinDef.h"
#include "SkinableGUIWnd.h"
#include "SkinableGUIImage.h"
#include "BitmapSlider/BitmapSlider.h"
// CSkinableGUIListBox

#include <map>

namespace SkinableGUI
{
	class CSkinableGUIListBox : public CSkinableGUIWnd
	{
		DECLARE_DYNAMIC(CSkinableGUIListBox)

	public:
		CSkinableGUIListBox(SkinListBox * pSkinListBox);
		virtual ~CSkinableGUIListBox();

	protected:
		DECLARE_MESSAGE_MAP()
	public:
		virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
		virtual BOOL CreateEx(DWORD dwExStyle, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam = NULL);

	protected:
		class CItemDataPtrMap : public std::map<UINT, void *>
		{
		};

		CStringArray m_Items;
		CItemDataPtrMap m_ItemDatas;

		CBitmap * m_pContentBitmap;

		CBitmap ** m_pSelectedItemBitmap;
		long m_nSelectedItemBitmapCount;

		UINT m_nHorzPos;
		UINT m_nVertPos;

		LONG m_nContentWidth;
		LONG m_nContentHeight;
		LONG m_nItemHeight;

		int m_nSelectedIndex;

		int m_nCurrentSelectedImageFrame;

		CSkinableGUIImage m_SelectedItemImage;
		CSkinableGUIImage m_NormalItemImage;

		BitmapSlider::CBitmapSlider m_HorzScrollBar;
		CSkinableGUIImage m_HorzScrollImages[4];

		BitmapSlider::CBitmapSlider m_VertScrollBar;
		CSkinableGUIImage m_VertScrollImages[4];

		void DestroyListBoxPainter(void);
		void PrepareContentPainter(CDC *  pDC, const CRect & rcClient);
		void DrawItem(CDC * pDC, 
			const CString & item, 
			const CRect & rcItem , 
			BOOL bSelected,
			int nItemSelectedImageIndex = 1,
			BOOL bDrawString = TRUE);
		CRect GetItemRect(int nIndex);
		void LoadScrollBar(SkinScrollBar * pScrollBar);
		CRect CalculateClientArea();
		CRect CalculateHorzScrollBarArea();
		CRect CalculateVertScrollBarArea();
		int CalculateHorzScrollBarHeight();
		int CalculateVertScrollBarWidth();
		void PrepareItemIndicatorDC();
		void DestroyItemIndicatorDC();
		void CreateScrollBar(BitmapSlider::CBitmapSlider & slider, 
										  SkinScrollBar & skinScrollBar, 
										  const CString & strTitle,
										  const CRect & rc,
										  CSkinableGUIImage images[4],
										  BOOL bVert,
										  UINT id = -1);

		void ContentRectToClient(CRect * lpRect);
		void FireSelectionChangeMessage();
		void ClientRectToContent(CRect * lpRect);

		virtual void DoRefreshWindow(const RECT * lpRect = NULL, BOOL bErase = TRUE);
	public:
		UINT AddString(const CString & item);
		CString GetItem(UINT nIndex);
		UINT GetItemCount() const { return m_Items.GetCount();  }
		int GetSelectedIndex() const { return m_nSelectedIndex; }
		void SetSelectedIndex(int nSelectedIndex);
		void ClearContent();
		void ScrollToVisible(UINT nIndex);
		void RemoveItem(UINT nIndex);
		void SetItemDataPtr(UINT nIndex, void * pData)
		{
			m_ItemDatas[nIndex] = pData;
		}

		void * GetItemDataPtr(UINT nIndex)
		{
			CItemDataPtrMap::iterator it = m_ItemDatas.find(nIndex);

			if (it == m_ItemDatas.end())
				return NULL;

			return it->second;
		}

	public:
		afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
		afx_msg void OnPaint();
		afx_msg void OnDestroy();
		afx_msg void OnSize(UINT nType, int cx, int cy);
		afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
		afx_msg void OnTimer(UINT_PTR nIDEvent);
		afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
		afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
		afx_msg void OnMouseMove(UINT nFlags, CPoint point);
		afx_msg LRESULT OnBitmapSliderMoving(WPARAM wParam, LPARAM lParam);
		afx_msg LRESULT OnBitmapSliderMoved(WPARAM wParam, LPARAM lParam);
		afx_msg void OnKillFocus(CWnd* pNewWnd);
		afx_msg void OnSetFocus(CWnd* pOldWnd);
	};

	enum 
	{
		WM_SKINABLE_LISTBOX_MSG_BASE = WM_SKINABLE_WINDOW_MSG_BASE +200,
		WM_SKINABLE_LISTBOX_SEL_CHANGE = WM_SKINABLE_LISTBOX_MSG_BASE
	};
}

